package utils;

import cn.hutool.extra.pinyin.PinyinUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelReader;
import com.alibaba.excel.read.listener.PageReadListener;
import com.alibaba.excel.read.metadata.ReadSheet;
import com.alibaba.fastjson2.JSON;
import constant.AttributeDataType;
import javafx.scene.control.Button;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
import lombok.extern.slf4j.Slf4j;
import model.*;
import model.excel.ReadLogisticsExcel;
import model.excel.ReadRequirementExcel;
import service.AttributeService;
import service.CustomerService;
import ui.MenuPage;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.IntConsumer;
import java.util.stream.Collectors;

/**
 * @Description excel导入工具
 * @Author zengzerui
 * @Date 2025/5/1
 */
@Slf4j
public class ExcelImportUtil {
    //读取客户信息
    public static void readLogisticsExcel() {

        FileChooser fileChooser = new FileChooser();
        fileChooser.setTitle("选择Excel文件");
        fileChooser.getExtensionFilters().add(
                new FileChooser.ExtensionFilter("Excel文件", "*.xlsx")
        );

        // 允许多选
        List<File> files = fileChooser.showOpenMultipleDialog(new Stage());


        if (files != null && !files.isEmpty()) {
            for (File file : files) {
                System.out.println("正在读取文件: " + file.getName());

                try (ExcelReader excelReader = EasyExcel.read(file.getAbsoluteFile()).build()) {
                    // 这里为了简单 所以注册了 同样的head 和Listener 自己使用功能必须不同的Listener
                    // 获取所有 Sheet
                    for (ReadSheet readSheet : excelReader.excelExecutor().sheetList()) {
                        System.out.println("正在读取 Sheet: " + readSheet.getSheetName());
                        // 动态构建 ReadSheet
                        Customer customer = new Customer();
                        ReadSheet dynamicReadSheet = EasyExcel.readSheet(readSheet.getSheetNo())
                                .head(ReadLogisticsExcel.class)
                                .registerReadListener(new PageReadListener<ReadLogisticsExcel>(dataList -> {        //获取所有属性
                                    List<AttributeDefinition> allAttributes = AttributeService.getAllAttributes();
                                    List<String> displayNames = allAttributes.stream()
                                            .map(AttributeDefinition::getDisplayName)
                                            .collect(Collectors.toList());

                                    AtomicInteger fieldOrder = new AtomicInteger(0); // 字段顺序计数器
                                    for (int i = 0; i < dataList.size(); i++) {
                                        ReadLogisticsExcel excelData = dataList.get(i);
                                        System.out.println("读取到一条数据: " + JSON.toJSONString(excelData));
                                        //判断这行是否存在
                                        if (!displayNames.contains(excelData.getItem()) && !("客户名称").equals(excelData.getItem())) {
                                            //如果不存在则需要添加到里面
                                            AttributeDefinition attributeDefinition = new AttributeDefinition();
                                            attributeDefinition.setDisplayName(excelData.getItem());
                                            attributeDefinition.setAttributeKey(generateAttributeKeyFromChinese(excelData.getItem()));
                                            attributeDefinition.setDataType(AttributeDataType.STRING);
                                            attributeDefinition.setDefaultValue("");
                                            AttributeService.addAttribute(attributeDefinition);
                                        }
                                        if (i == 0){
                                            //添加客户信息
                                            customer.setCustomerName(excelData.getContent());
                                        }
                                        //添加属性信息
                                        allAttributes = AttributeService.getAllAttributes();
                                        for (AttributeDefinition attributeDefinition : allAttributes) {
                                            if (attributeDefinition.getDisplayName().equals(excelData.getItem())){
                                                customer.getAttributeValues().put(attributeDefinition.getAttributeId(), excelData.getContent());
                                                // 设置默认不高亮
                                                customer.setAttributeHighlight(attributeDefinition.getAttributeId(), false);
                                            }
                                        }

                                    }
                                    // 当处理完一个sheet的所有数据后，插入数据库
                                    CustomerService customerService = new CustomerService();
                                    customerService.addCustomer(customer);
                                }))
                                .headRowNumber(2)
                                .build();
                        excelReader.read(dynamicReadSheet);
                    }
                }
            }
        } else {
            System.out.println("未选择任何文件");
        }
        //读取完之后，刷新页面

    }

    //导入物流需求
    public static void readRequirement(){
        FileChooser fileChooser = new FileChooser();
        fileChooser.setTitle("选择Excel文件");
        fileChooser.getExtensionFilters().add(
                new FileChooser.ExtensionFilter("Excel文件", "*.xlsx")
        );
        File file = fileChooser.showOpenDialog(new Stage());
        // 这里默认每次会读取100条数据 然后返回过来 直接调用使用数据就行
        // 具体需要返回多少行可以在`PageReadListener`的构造函数设置
        EasyExcel.read(file.getAbsoluteFile(), ReadRequirementExcel.class, new PageReadListener<ReadRequirementExcel>(dataList -> {
            for (ReadRequirementExcel excelData : dataList) {
                LogisticsRequirement requirement = new LogisticsRequirement();
                requirement.setItem(excelData.getItem());
                requirement.setRequirement(excelData.getRequirement());
                requirement.setProEffi(excelData.getProEffi());
                requirement.setSupervisor(excelData.getSupervisor());
                requirement.setResponsiblePerson(excelData.getResponsiblePerson());
                DBUtil.insertLogisticsRequirement(requirement);
            }
        })).head(ReadRequirementExcel.class).
                headRowNumber(1)
                .sheet().doRead();

    }
    public static String generateAttributeKeyFromChinese(String displayName) {
        if (displayName == null || displayName.isEmpty()) {
            return "";
        }
        // 1. 中文转拼音（不带音调）
        String pinyin = PinyinUtil.getPinyin(displayName, "");
        // 2. 转小写，替换非字母数字为下划线
        String key = pinyin.toLowerCase()
                .replaceAll("[^a-z0-9]", "_");
        // 3. 移除连续下划线
        key = key.replaceAll("_+", "_");
        return key;
    }

    //根据从excel读出来的数据，构建LogisticsInfo对象
    private static void setLogisticsInfoByOrder(LogisticsInfo logisticsInfo, String content, int fieldOrder) {
        if (content == null || content.trim().isEmpty())
            return;

        try {
            switch (fieldOrder) {
                // 前5个基础字段
                case 0:
                    logisticsInfo.setName(content);
                    break;          // 客户名称
                case 1:
                    logisticsInfo.setAddress(content);
                    break;     // 仓库地址
                case 2:
                    logisticsInfo.setKm(parseInt(content));
                    break; // 里程(km)
                case 3:
                    logisticsInfo.setContacts(content);
                    break;     // 客户联系人
                case 4:
                    logisticsInfo.setTimeInput(content);
                    break;    // 到达时间要求

                // 温度相关字段（特殊处理）
                case 5:
                    logisticsInfo.setIsFirstBattleArrival(content);
                    break; // 是否首战
                case 6:
                    parseTemperatureRange(content,
                            logisticsInfo::setTruckTempMin,
                            logisticsInfo::setTruckTempMax);
                    break; // 车厢温度要求
                case 7:
                    parseTemperatureRange(content,
                            logisticsInfo::setProductTempMin,
                            logisticsInfo::setProductTempMax);
                    break; // 产品温度要求

                // 设备相关字段
                case 8:
                    logisticsInfo.setMeasureMethod(content);
                    break;  // 测温方式
                case 9:
                    logisticsInfo.setEquipmentType(content);
                    break;  // 温控设备类型
                case 10:
                    logisticsInfo.setEquipmentNum(content);
                    break;  // 温控设备数量

                // 物流操作选项（是/否类字段）
                case 11:
                    logisticsInfo.setOpenBox(parseYesNo(content));
                    break;     // 是否开箱测温
                case 12:
                    logisticsInfo.setTrayTransport(parseYesNo(content));
                    break; // 是否带托运输
                case 13:
                    logisticsInfo.setUnloadingService(parseYesNo(content));
                    break; // 是否卸货服务
                case 14:
                    logisticsInfo.setUnloadingCost(content);
                    break; // 卸货费用

                // 流程要求
                case 15:
                    logisticsInfo.setAppointment(parseYesNo(content));
                    break; // 是否需要预约
                case 16:
                    logisticsInfo.setDocumentNeed(content);
                    break;  // 随车单据要求
                case 17:
                    logisticsInfo.setStampConfirm(parseYesNo(content));
                    break; // 是否盖章确认
                case 18:
                    logisticsInfo.setReplaceBox(parseYesNo(content));
                    break;  // 是否能换箱
                case 19:
                    logisticsInfo.setDelayAccept(parseYesNo(content));
                    break; // 是否延迟收货
                case 20:
                    logisticsInfo.setOtherNeeds(content);
                    break;   // 其他需求

                default:
                    System.out.println("[警告] 忽略多余字段，顺序号: " + fieldOrder);
            }
        } catch (Exception e) {
            System.err.println("[错误] 字段处理失败(顺序号=" + fieldOrder + "): " +
                    content + " | 错误: " + e.getMessage());
        }
    }

    // === 工具方法 ===
// 解析温度范围（如 "0-4°C" -> min=0, max=4）
    private static void parseTemperatureRange(String rangeStr, IntConsumer minSetter, IntConsumer maxSetter) {
        String cleaned = rangeStr.replaceAll("[^0-9-]", ""); // 移除非数字和减号
        String[] parts = cleaned.split("-");
        if (parts.length == 2) {
            minSetter.accept(parseInt(parts[0]));
            maxSetter.accept(parseInt(parts[1]));
        } else {
            throw new IllegalArgumentException("温度范围格式错误，应为'min-max'");
        }
    }

    // 统一处理数值转换（含空值检查）
    private static int parseInt(String str) {
        if (str == null || str.trim().isEmpty()) return 0;
        return Integer.parseInt(str.replaceAll("[^0-9]", ""));
    }

    // 统一处理是/否选项（支持"是"/"否"、"需要"/"不需要"等多种表述）
    private static String parseYesNo(String str) {
        if (str == null) return "否";
        return str.matches("(?i)(是|需要|必须|要求|√|yes|true)") ? "是" : "否";
    }

}
